package gtkwire.widget;

import gtkwire.*;
import java.util.Vector;
import java.util.Random;

/**
*Base class for all widget handles.
*/
public class GtkWidget
{


	public static final String WT_GtkAspectFrame = "GtkAspectFrame";
	public static final String WT_GtkAboutDialog = "GtkAboutDialog";
	public static final String WT_GtkAlignment = "GtkAlignment";
	public static final String WT_GtkBin = "GtkBin";
	public static final String WT_GtkBox = "GtkBox";
	public static final String WT_GtkButton = "GtkButton";
	public static final String WT_GtkButtonBox = "GtkButtonBox";
	public static final String WT_GtkCairoDrawable = "GtkCairoDrawable";
	public static final String WT_GtkCheckButton = "GtkCheckButton";
	public static final String WT_GtkCheckMenuItem = "GtkCheckMenuItem";
	public static final String WT_GtkColorButton = "GtkColorButton";
	public static final String WT_GtkColorSelectionDialog = "GtkColorSelectionDialog";
	public static final String WT_GtkComboBox = "GtkComboBox";
	public static final String WT_GtkComboBoxEntry = "GtkComboBoxEntry";
	public static final String WT_GtkContainer = "GtkContainer";
	public static final String WT_GtkDialog = "GtkDialog";
	public static final String WT_GtkDrawableArea = "GtkDrawableArea";
	public static final String WT_GtkEntry = "GtkEntry";
	public static final String WT_GtkExpander = "GtkExpander";
	public static final String WT_GtkFileChooserButton = "GtkFileChooserButton";
	public static final String WT_GtkFileChooserDialog = "GtkFileChooserDialog";
	public static final String WT_GtkFileSelection = "GtkFileSelection";
	public static final String WT_GtkFontButton = "GtkFontButton";
	public static final String WT_GtkFontSelectionDialog = "GtkFontSelectionDialog";
	public static final String WT_GtkFrame = "GtkFrame";
	public static final String WT_GtkHBox = "GtkHBox";
	public static final String WT_GtkHButtonBox = "GtkHButtonBox";
	public static final String WT_GtkHPaned = "GtkPaned";
	public static final String WT_GtkHScale = "GtkHScale";
	public static final String WT_GtkHSeparator = "GtkHSeparator";
	public static final String WT_GtkImage = "GtkImage";
	public static final String WT_GtkImageMenuItem = "GtkImageMenuItem";
	public static final String WT_GtkInputDialog = "GtkInputDialog";
	public static final String WT_GtkItem = "GtkItem";
	public static final String WT_GtkLabel = "GtkLabel";
	public static final String WT_GtkMenu = "GtkMenu";
	public static final String WT_GtkMenuBar = "GtkMenuBar";
	public static final String WT_GtkMenuItem = "GtkMenuItem";
	public static final String WT_GtkMenuShell = "GtkMenuShell";
	public static final String WT_GtkMenuToolButton = "GtkMenuToolButton";
	public static final String WT_GtkMessageDialog  = "GtkMessageDialog";
	public static final String WT_GtkMisc = "GtkMisc";
	public static final String WT_GtkNotebook = "GtkNotebook";
	public static final String WT_GtkPaned = "GtkPaned";
	public static final String WT_GtkPageSetupUnixDialog = "GtkPageSetupUnixDialog";
	public static final String WT_GtkRecentChooserDialog = "GtkRecentChooserDialog";
	public static final String WT_GtkPrintUnixDialog = "GtkPrintUnixDialog";
	public static final String WT_GtkProgress = "GtkProgress";
	public static final String WT_GtkProgressBar = "GtkProgressBar";
	public static final String WT_GtkRadioButton = "GtkRadioButton";
	public static final String WT_GtkRadioToolButton = "GtkRadioToolButton";
	public static final String WT_GtkRange = "GtkRange";
	public static final String WT_GtkScale = "GtkScale";
	public static final String WT_GtkScrolledWindow = "GtkScrolledWindow";
	public static final String WT_GtkSeparatorToolItem = "GtkSeparatorToolItem";
	public static final String WT_GtkSpinButton = "GtkSpinButton";
	public static final String WT_GtkStatusbar = "GtkStatusbar";
	public static final String WT_GtkTable = "GtkTable";
	public static final String WT_GtkTextView = "GtkTextView";
	public static final String WT_GtkToggleButton = "GtkToggleButton";
	public static final String WT_GtkToggleToolButton = "GtkToggleToolButton";
	public static final String WT_GtkToolItem = "GtkToolItem";
	public static final String WT_GtkToolbar = "GtkToolbar";
	public static final String WT_GtkToolButton = "GtkToolButton";
	public static final String WT_GtkTreeView = "GtkTreeView";
	public static final String WT_GtkVBox = "GtkVBox";
	public static final String WT_GtkVButtonBox = "GtkVButtonBox";
	public static final String WT_GtkVPaned = "GtkVPaned";
	public static final String WT_GtkVScale = "GtkVScale";
	public static final String WT_GtkWidget = "GtkWidget";
	public static final String WT_GtkWindow = "GtkWindow";

	/**
	* User defined name of the widget. This is unique ID String widgets. If these are not unique for alll widgets, behaviour is undetermined.
	*/
	protected String name;
	/**
	* Type of the widget.
	*/	
	protected String widgetType;

	/**
	*Flag used when constructing widget to see if they are to be added to autoCreateVec.
	*/
	private static boolean createCollect = false;
	/**
	*Vector of created widget handles. Corresponding GTK+ widgets are created when 
	* autoCreateCollected() is called.
	*/
	public static Vector<GtkWidget> autoCreateVec = new Vector<GtkWidget>();
	/**
	*Signals that are auto connected at creation time if autoConnectSignals == true.
	*Subclasses set this in constructor for different widget types.
	*/
	protected GTKWireSignal[] autoSignals = null;
	/**
	*Flag for signal auto connecting.
	*/
	private static boolean autoConnectSignals = true;
	/**
	*Dummy message for inner use. This is also a flag for permitting crating of objacts 
	* that don't provide data et creation time.
	*/
	protected static final String[] emptyMsg = {""};
	/**
	* Increasing id for quaranteed unique in auto name creating
	*/
	protected static int nameId = 1234;
	/**
	* Used to get variation in auto name creating.
	*/
	protected static Random rand = new Random();

	protected GtkWidget()
	{
		name = Integer.toString( rand.nextInt(10000) ) + ":" + Integer.toString( nameId );
		nameId++;
	}

	protected GtkWidget( String name, GladeKey key )
	{
		this.name = name;
	}

	/**
	* Returns widgets unique name.
	*/
	public String getName(){ return name; }

	/**
	* Tests if message is sent from gtk object represented by this object.
	*/
	public boolean isSource( GTKWireMessage msg )
	{
		if( msg.getWidgetType().equals( widgetType )
			&& msg.getWidgetName().equals( name ) ) return true;

		return false;
	}

	/**
	* Returns the singleton instance of GtkWireApp.
	*/	
	protected GTKWireApp app(){ return GTKWireApp.instance(); }

	public String getWidgetType(){ return widgetType; }
	protected void setWidgetType( String widgetType ){ this.widgetType = widgetType; }
	
	public boolean isMatch( String matchWidgetType )
	{
		if( matchWidgetType.equals( widgetType ) ) return true;
		return false;
	}

	//--------------------------------------------------------------- Gtk create methods
	/**
	*Creates a real GTK+ object instance. Also creates a data structure in c -side of this lib for later acces.
	*Unless this is called widget is just a handle used to connect to 
	*widgets created using Glade.
	*/
	protected void gtkCreate()
	{
		if( getCreateData() == null ) return;	//--- null defined to mean that we are trying 
							//--- to create widget from super type 
							//--- in a GtkWidget hierarchy path 
							//--- that has multiple instantiable widgets, so exit.
		app().createGTKWidget( getWidgetType(), getName(), getCreateData() );
	}

	/**
	* Connects GTK+ widget with given signals.
	*/
	public void connectSignals( Vector<GTKWireSignal> connectSignals )
	{
		app().connectSignals( this, connectSignals );
	}

	/**
	* Some widgets override this to provide data at gtk creation time 
	* or to block creating widgets for super classes.
	*/
	protected String[] getCreateData(){ return emptyMsg; }

	//-------------------------------------------------------------- GtkWidget methods
	/**Destroys a widget. If the widget is inside a container, the widget will be removed from the container. 
	*If the widget is a toplevel (derived *from GtkWindow), it will be removed from the list of toplevels,
	*and the reference GTK+ holds to it will be removed.
	*In most cases, only toplevel widgets (windows) require explicit destruction, 
	*because when you destroy a toplevel its children will be destroyed as well.
	*/
	public void destroy()
	{ 
		app().sendCommand( name, GTKWireCommand.DESTROY_WIDGET );
	}
	/**
	*Reverses the effects of gtk_widget_show(), causing the widget to be invisible.
	*/
	public void hide(){ app().sendCommand( name, GTKWireCommand.HIDE ); }
	/**
	*Flags a widget to be displayed. Any widget that isn't shown will not appear on the screen.
	*<p>
	*Remember that you have to show the containers containing a widget, in addition to the widget itself, before it will appear onscreen.
	*When a toplevel container is shown, it is immediately realized and mapped; 
	*other shown widgets are realized and mapped when their toplevel container is realized and mapped.
	*/
	public void show(){ app().sendCommand( name, GTKWireCommand.SHOW ); }
	/**
	*Recursively shows a widget, and any child widgets (if the widget is a container).
	*/
	public void showAll(){ app().sendCommand( name, GTKWireCommand.SHOW_ALL ); }
	/**Sets the sensitivity of a widget. A widget is sensitive if the user can interact with it. 
	*Insensitive widgets are "grayed out" and the user can't interact with them.
	*/
	public void setSensitive( boolean val ){ app().sendCommand( name, GTKWireCommand.SET_SENSITIVE, val ); }
	/**
	*Sets text as the contents of the tooltip.
	*/
	public void setTooltip( String text ){ app().sendCommand( name, GTKWireCommand.SET_TOOLTIP, text ); }
	/**Causes widget to have the keyboard focus for the GtkWindow it's inside. 
	*widget must be a focusable widget, such as a GtkEntry; something like GtkFrame won't work.
	*/
	public void grabFocus(){ app().sendCommand( name, GTKWireCommand.GRAB_FOCUS ); }
	/**
	*Returns true if the widget is the focus widget within its toplevel.
	*/
	public boolean hasFocus()
	{
		GTKWireMessage answer = app().sendCommandRequest( name, widgetType, GTKWireCommandRequest.HAS_FOCUS, null );
		if( answer == null ) return false;//?
		return ((Boolean)answer.getMessageObject()).booleanValue();
	}
	/**
	*Returns true if widget is visible.
	*/
	public boolean isVisible()
	{
		GTKWireMessage answer = app().sendCommandRequest( name, widgetType, GTKWireCommandRequest.IS_VISIBLE, null );
		if( answer == null ) return false;
		return((Boolean)answer.getMessageObject()).booleanValue();
	}

	public void sizeRequest( int width, int height )
	{
		int[] msg = new int[2];
		msg[0] = width;
		msg[1] = height;
		app().sendCommand( name, GTKWireCommand.SIZE_REQUEST, msg);
	}

}//end class
